package com.sk.waste.app.utils

import com.lc.smc.lib.interfaces.LCInterface
import com.lc.smc.lib.utils.LCBaseUtil
import com.lc.smc.lib.utils.LCLogger
import okhttp3.Call
import okhttp3.Callback
import okhttp3.MediaType
import okhttp3.MultipartBody
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody
import okhttp3.Response
import okhttp3.WebSocket
import okhttp3.WebSocketListener
import okio.ByteString
import org.json.JSONObject
import java.io.File
import java.io.IOException
import java.util.concurrent.TimeUnit


/**
 *  @time 2024/4/26  16:23
 *  @author Im_jingwei
 *  @desc 网络请求类
 */
class OkHttpUtil {

    val JSON = MediaType.parse("application/json; charset=utf-8")

    /**
     *  @time 2024/4/28  9:16
     *  @author Im_jingwei
     *  @desc get 请求 无token
     *  @param url 请求地址、callback 回调接口
     */
    fun httpRequestGet(url: String, callback: Any?) {
        httpRequestGet(url, null, callback)
    }

    /**
     *  @time 2024/4/28  9:16
     *  @author Im_jingwei
     *  @desc get 请求 token
     *  @param url 请求地址、token 、callback 回调接口
     */
    fun httpRequestGet(url: String, token: String?, callback: Any?) {
        val client = getOkHttpClient(url)
        val builder = Request.Builder().url(url)
        if (!LCBaseUtil.isNull(token)) {
            builder.addHeader("Authorization", token)
        }
        val request = builder.build()
        printRequestLog("get", url!!, "")
        client.newCall(request).enqueue(object : Callback {
            override fun onFailure(call: Call, e: IOException) {
                printResponseLog("failed!", url, e.message.toString());
                if (callback is LCInterface.LcCallBackListener) {
                    callback.onFailure(call, e)
                } else if (callback is Callback) {
                    callback.onFailure(call, e)
                }
            }

            override fun onResponse(call: Call, response: Response) {
                if (response.code() == 200) {
                    if (callback is LCInterface.LcCallBackListener) {
                        val body = response.body()!!.string()
                        printResponseLog("success!", url, body);
                        callback.onSuccess(call, body)
                    } else if (callback is Callback) {
                        printResponseLog("success!", url, response.body().toString());
                        callback.onResponse(call, response)
                    }
                } else {
                    printResponseLog("success!", url, response.message());
                }
            }
        })
    }

    /**
     *  @time 2024/4/28  9:16
     *  @author Im_jingwei
     *  @desc post 请求 无token
     *  @param url 请求地址、json 请求报文、callback 回调接口
     */
    fun httpRequest(url: String, json: String?, callback: Any?) {
        httpRequest(url, null, json, callback)
    }

    /**
     *  @time 2024/4/28  9:16
     *  @author Im_jingwei
     *  @desc post 请求 token
     *  @param url 请求地址、token、json 请求报文、callback 回调接口
     */
    fun httpRequest(url: String, token: String?, json: String?, callback: Any?) {

        val client = getOkHttpClient(url)
        val requestBody = RequestBody.create(JSON, json)
        val builder = Request.Builder()
            .url(url)
            .post(requestBody)
        if (!LCBaseUtil.isNull(token)) {
            builder.addHeader("Authorization", token)
        }
        val request = builder.build()
        printRequestLog("post", url, json.toString())
        client.newCall(request).enqueue(object : Callback {
            override fun onFailure(call: Call, e: IOException) {
                printResponseLog("failed!", url, e.message.toString());
                if (callback is LCInterface.LcCallBackListener) {
                    callback.onFailure(call, e)
                } else if (callback is Callback) {
                    callback.onFailure(call, e)
                }
            }

            override fun onResponse(call: Call, response: Response) {
                if (response.code() == 200) {
                    if (callback is LCInterface.LcCallBackListener) {
                        val body = response.body()!!.string()
                        printResponseLog("success!", url, body);
                        callback.onSuccess(call, body)
                    } else if (callback is Callback) {
                        printResponseLog("success!", url, response.body().toString());
                        callback.onResponse(call, response)
                    }
                } else {
                    val exception = IOException(response.message())
                    printResponseLog("failed!", url, response.message());
                    if (callback is LCInterface.LcCallBackListener) {
                        callback.onFailure(call, exception)
                    } else if (callback is Callback) {
                        callback.onFailure(call, exception)
                    }
                }
            }
        })

    }

    /**
     *  @time 2024/4/28  9:16
     *  @author Im_jingwei
     *  @desc post 请求 token
     *  @param url 请求地址、token、json 请求报文、callback 回调接口
     */
    fun httpRequestPut(url: String, token: String?, json: String?, callback: Any?) {

        val client = getOkHttpClient(url)
        val requestBody = RequestBody.create(JSON, json)
        val builder = Request.Builder()
            .url(url)
            .put(requestBody)
        if (!LCBaseUtil.isNull(token)) {
            builder.addHeader("Authorization", token)
        }
        val request = builder.build()
        printRequestLog("put", url!!, json.toString())
        client.newCall(request).enqueue(object : Callback {
            override fun onFailure(call: Call, e: IOException) {
                printResponseLog("failed!", url, e.message.toString());
                if (callback is LCInterface.LcCallBackListener) {
                    callback.onFailure(call, e)
                } else if (callback is Callback) {
                    callback.onFailure(call, e)
                }
            }

            override fun onResponse(call: Call, response: Response) {
                if (response.code() == 200) {
                    if (callback is LCInterface.LcCallBackListener) {
                        val body = response.body()!!.string()
                        printResponseLog("success!", url, body);
                        callback.onSuccess(call, body)
                    } else if (callback is Callback) {
                        printResponseLog("success!", url, response.body().toString());
                        callback.onResponse(call, response)
                    }
                } else {
                    val exception = IOException(response.message())
                    printResponseLog("failed!", url, response.message());
                    if (callback is LCInterface.LcCallBackListener) {
                        callback.onFailure(call, exception)
                    } else if (callback is Callback) {
                        callback.onFailure(call, exception)
                    }
                }
            }
        })

    }

    /**
     *  @time 2024/5/14  15:20
     *  @author Im_jingwei
     *  @desc websocket 测试代码 预留使用
     */
    fun socketRequest() {
        val client = OkHttpClient()
        val request = Request.Builder()
            .url("ws://example.com/websocket")
            .build()
        val webSocket: WebSocket = client.newWebSocket(request, object : WebSocketListener() {
            override fun onOpen(webSocket: WebSocket, response: Response) {
                // 连接打开时的回调
                webSocket.send("连接已建立，发送消息测试。")
            }

            override fun onMessage(webSocket: WebSocket, text: String) {
                // 接收到文本消息时的回调
                println("接收到文本消息：$text")
            }

            override fun onMessage(webSocket: WebSocket, bytes: ByteString) {
                // 接收到二进制消息时的回调
                println("接收到二进制消息：" + bytes.hex())
            }

            override fun onClosing(webSocket: WebSocket, code: Int, reason: String) {
                // 对方启始关闭握手
                webSocket.close(1000, "关闭连接。")
            }

            override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
                // 连接失败时的回调
                t.printStackTrace()
            }
        })
    }

    /**
     *  @time 2024/9/5  13:46
     *  @author Im_jingwei
     *  @desc 文件上传
     */
    fun httpRequestFile(url: String, token: String, mediaTyle: String, filePath: String, params: HashMap<String, String>, callback: Any?) {
        val client = getOkHttpClient(url)
        val file = File(filePath)  // 需要上传的文件
        val fileBody = RequestBody.create(MediaType.parse("${mediaTyle}/*"), file)//"multipart/form-data"
        val requestBody = MultipartBody.Builder()
            .setType(MultipartBody.FORM)
            .addFormDataPart("file", file.name, fileBody)
        for (entry in params.entries) {
            requestBody.addFormDataPart(entry.key, entry.value)
        }
        val request = Request.Builder()
            .url(url)
            .addHeader("Authorization", token)
            .post(requestBody.build())
        try {
            client.newCall(request.build()).enqueue(object : Callback {
                override fun onFailure(call: Call, e: IOException) {
                    printResponseLog_e("failed!", "$url\nfile: $filePath", e.message.toString());
                    if (callback is LCInterface.LcCallBackListener) {
                        callback.onFailure(call, e)
                    } else if (callback is Callback) {
                        callback.onFailure(call, e)
                    }
                }

                override fun onResponse(call: Call, response: Response) {
                    if (response.code() == 200) {
                        if (callback is LCInterface.LcCallBackListener) {
                            val body = response.body()!!.string()
                            printResponseLog("success!", "$url\nfile: $filePath", body);
                            callback.onSuccess(call, body)
                        } else if (callback is Callback) {
                            printResponseLog("success!", "$url\nfile: $filePath", response.body().toString());
                            callback.onResponse(call, response)
                        }
                    } else {
                        printResponseLog("failed!", "$url\nfile: $filePath", "responseCode: " + response.code() + "  msg: " + response.message());
                    }
                }
            })
        } catch (e: IOException) {
            e.printStackTrace()
        }
    }

    /**
     *  @time 2024/5/6  14:51
     *  @author Im_jingwei
     *  @desc 返回OkHttpClient
     */
    fun getOkHttpClient(url: String): OkHttpClient {
        if (url.contains("https")) {
            val sslcomment = OkHttpSSL()
            val client = OkHttpClient().newBuilder()
            client.sslSocketFactory(sslcomment.sSLSocketFactory, sslcomment.x509TrustManager)
            client.hostnameVerifier(sslcomment.hostnameVerifier)
            client.connectTimeout(10, TimeUnit.SECONDS) // 设置连接超时时间
            client.readTimeout(60, TimeUnit.SECONDS)    // 设置读取超时时间
            client.writeTimeout(15, TimeUnit.SECONDS)   // 设置写入超时时间
            return client.build()
        } else {
            return OkHttpClient.Builder()
                .connectTimeout(10, TimeUnit.SECONDS) // 设置连接超时时间
                .readTimeout(60, TimeUnit.SECONDS)    // 设置读取超时时间
                .writeTimeout(15, TimeUnit.SECONDS)   // 设置写入超时时间
                .build()
        }

    }

    /**
     *  @time 2024/7/8  16:35
     *  @author Im_jingwei
     *  @desc 打印请求报文
     */
    fun printRequestLog(type: String, url: String, params: String) {
        LCLogger.d("LCLOG_OKHTTP_REQUEST", "request type:$type \nurl:$url" + "\nparams:$params");
    }

    /**
     *  @time 2024/7/8  16:36
     *  @author Im_jingwei
     *  @desc 打印返回报文
     */
    fun printResponseLog(state: String, url: String, response: String) {
        LCLogger.d("LCLOG_OKHTTP_RESPONSE", "response state:$state \nurl:$url" + "\ndatas:$response");
    }

    /**
     *  @time 2024/7/8  16:36
     *  @author Im_jingwei
     *  @desc 打印返回报文
     */
    fun printResponseLog_e(state: String, url: String, response: String) {
        LCLogger.e("LCLOG_OKHTTP_RESPONSE", "response state:$state \nurl:$url" + "\ndatas:$response");
    }

}